package com.smrs.goods.service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;

import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.jof.framework.dao.hibernate.BaseDAOHibernateImpl;
import com.jof.framework.util.ExecuteResult;
import com.jof.framework.util.Pager;
import com.smrs.enums.StatusEnum;
import com.smrs.goods.dao.GoodsSkuDao;
import com.smrs.goods.model.GoodsAttributeModel;
import com.smrs.goods.model.GoodsAttributeValueModel;
import com.smrs.goods.model.GoodsSkuAttributeModel;
import com.smrs.goods.model.GoodsSkuModel;
import com.smrs.service.BaseService;

@Component(value = "goodsSkuService")
public class GoodsSkuService extends BaseService<GoodsSkuModel, Long> {

	@Autowired
	private GoodsSkuDao goodsSkuDao;
	
	@Autowired
	private GoodsAttributeValueService goodsAttributeValueService;
	
	@Autowired
	private GoodsSkuAttributeService goodsSkuAttributeService;
	
	@Autowired
	protected GoodsCategoryService goodsCategoryService;
	@Autowired
	protected GoodsAttributeService goodsAttributeService;
	/*
	 * public Pager<RegionModel> getByNameLikePager(final RegionSearchModel
	 * model){ String name = model.getRegion().getName(); Pager<RegionModel>
	 * pager = goodsItemDao.getByNameLikePager(name,model.getPager()); return
	 * pager; //return null; }
	 */
	public Pager<GoodsSkuModel> getByNameLikePager(String name, Pager<GoodsSkuModel> pager) {
		// String name = model.getRegion().getName();
		Pager<GoodsSkuModel> tempPager = getPerformDao().getByNameLikePager(name, pager);
		return tempPager;
		// return null;
	}

	public  Pager<GoodsSkuModel> findBySku(GoodsSkuModel sku, Pager<GoodsSkuModel> pager){
		 Pager<GoodsSkuModel> tempPager=goodsSkuDao.findBySku(sku, pager);
		return tempPager;
	}
	
	
	
	public List<GoodsSkuModel> findByItemId(Long itemId){
		List<GoodsSkuModel> list = goodsSkuDao.getByItemId(itemId);
		return list;
	}
	
	public List<GoodsSkuModel> findByItemIdWithAttrValues(Long itemId){
		List<GoodsSkuModel> skuList = goodsSkuDao.getByItemId(itemId);
		if(CollectionUtils.isNotEmpty(skuList)){
			for(GoodsSkuModel sku:skuList){
				List<GoodsSkuAttributeModel> skuAttrList = goodsSkuAttributeService.getSkuAttributeBySkuId(sku.getId());
				sku.getSkuAttributes().addAll(skuAttrList);
			}
		}
		return skuList;
	}
	public Pager<GoodsSkuModel> findByItemId(Long itemId, Pager<GoodsSkuModel> pager) {
		List<GoodsSkuModel> list = goodsSkuDao.getByItemId(itemId);		
		Long count =Long.valueOf(list.size());		
		Pager<GoodsSkuModel> tempPager = Pager.cloneFromPager(pager, count, list);
		return tempPager;		
	}
	
	
	@Override
	public BaseDAOHibernateImpl<GoodsSkuModel, Long> getPerformDao() {
		return goodsSkuDao;
	}

	public HashMap<Long, List<GoodsAttributeValueModel>> prepareSkuAttributeValue(String[] selectedAttributeValues) {
		HashMap<Long, List<GoodsAttributeValueModel>> attributeMap = new HashMap<Long, List<GoodsAttributeValueModel>>();
		if (selectedAttributeValues != null && selectedAttributeValues.length != 0) {
			for (int index = 0; index < selectedAttributeValues.length; index++) {
				Long attributeValueId = Long.parseLong(selectedAttributeValues[index]);
				GoodsAttributeValueModel valueModel = goodsAttributeValueService.getByPK(attributeValueId);
				List<GoodsAttributeValueModel> list = attributeMap.get(valueModel.getGoodsAttribute().getId());
				if (list == null) {
					list = new ArrayList<GoodsAttributeValueModel>();
				}
				list.add(valueModel);
				attributeMap.put(valueModel.getGoodsAttribute().getId(), list);
			}
		}
		return attributeMap;
	}

	
	public ExecuteResult<String>   checkSelectAllAttribute(Long itemId,Set<Long> selectedAttributes){
		ExecuteResult<String> result = new ExecuteResult<String>();
		LinkedHashSet<GoodsAttributeModel> listSet = goodsCategoryService.getAllAttributeByItemId(itemId);
		ArrayList<Long> listAttr = new ArrayList<Long>();
		if(listSet!=null && listSet.size()>0){
			for(GoodsAttributeModel attr:listSet){
				listAttr.add(attr.getId());
			}
		}
		listAttr.removeAll(selectedAttributes);
		if(listAttr!=null && listAttr.size()>0){
			Long attrId = listAttr.get(0);
			GoodsAttributeModel attrModel = goodsAttributeService.getByPK(attrId);
			List<String> list = new ArrayList<String>();
			list.add("可选择属性值中，必须每个属性至少选择一个,请选择 :" + attrModel.getName());
			result.setErrorMessages(list);			
		}
		return result;
	}
	
	public  ExecuteResult<String> updateSkuToDatabase(GoodsSkuModel skuModel,String[] selectedAttributeValues){
		ExecuteResult<String> result = new ExecuteResult<String>();
		//得到这个item 所有的sku 的attrValueId
		List<GoodsSkuAttributeModel>  list = goodsSkuAttributeService.getSkuAttributeByItemId(skuModel.getItemId());
		LinkedHashSet<Long>  existLinkedSet = new LinkedHashSet<Long>();
		if(CollectionUtils.isNotEmpty(list)){
			for(GoodsSkuAttributeModel skuAttr:list){
				existLinkedSet.add(skuAttr.getAttributeValueId());
			}
		}
		//从页面选择的attrValueIds
		LinkedHashSet<Long>  selectedLinkedSet = new LinkedHashSet<Long>();
		for(int index=0;index<selectedAttributeValues.length;index++){
			selectedLinkedSet.add(Long.parseLong(selectedAttributeValues[index]));
		}
		existLinkedSet.removeAll(selectedLinkedSet);
		//需要移除的属性值
		LinkedHashSet<Long> removeExistAttrValue=existLinkedSet;
		if(removeExistAttrValue!=null && removeExistAttrValue.size()>0){
			Long removeAttrValueId = removeExistAttrValue.iterator().next();
			GoodsAttributeValueModel attrValueModel=goodsAttributeValueService.getByPK(removeAttrValueId);
			result.addErrorMessage("修改只能增加属性，不能删除属性,不要删除 : "+ attrValueModel.getGoodsAttribute().getName()+ " "+attrValueModel.getName());
			return result;
		}
		
		//得到这个item 所有的sku 的attrValueId
		existLinkedSet = new LinkedHashSet<Long>();
		if(CollectionUtils.isNotEmpty(list)){
			for(GoodsSkuAttributeModel skuAttr:list){
				existLinkedSet.add(skuAttr.getAttributeValueId());
			}
		}
		//得到页面新增的attrValueIds
		selectedLinkedSet.removeAll(existLinkedSet);
		//需要新建的属性值
		LinkedHashSet<Long>  newSelectedLinkedSet = selectedLinkedSet;
		updateItemAddSkuAddNewAttrValue(newSelectedLinkedSet,skuModel);
		return result;
	}
	
	
	public ExecuteResult<String> updateItemAddSkuAddNewAttrValue(LinkedHashSet<Long>  newSelectedLinkedSet,GoodsSkuModel skuModel){
		ExecuteResult<String> result = new ExecuteResult<String>();		
		for(Long newAttrValueId:newSelectedLinkedSet){
			List<GoodsSkuModel> skuList = findByItemIdWithAttrValues(skuModel.getItemId());
			GoodsAttributeValueModel attrValueModel=goodsAttributeValueService.getByPK(newAttrValueId);
			for(GoodsSkuModel oneSku:skuList){
				GoodsSkuModel newSku = cloneSku(oneSku);
				newSku.setId(null);
				List<Long> addedAttributeIds = new ArrayList<Long>();
				Iterator<GoodsSkuAttributeModel> iterator = newSku.getSkuAttributes().iterator();
				while(iterator.hasNext()){
					GoodsSkuAttributeModel skuAttr = iterator.next();
					if(skuAttr.getAttributeId().equals(attrValueModel.getGoodsAttribute().getId())){
						//对于已近处理过的attributeId, 不再处理，一个attribute 只处理一次
						if(addedAttributeIds.contains(skuAttr.getAttributeId()))
							continue;
						addedAttributeIds.add(skuAttr.getAttributeId());
						GoodsSkuAttributeModel tempSkuAttr = new GoodsSkuAttributeModel();
						BeanUtils.copyProperties(skuAttr, tempSkuAttr);
						tempSkuAttr.setId(null);
						//删除原来这个attribute value(如size 36)
						newSku.getSkuAttributes().remove(skuAttr);						
						tempSkuAttr.setAttributeValue(attrValueModel.getValue());
						tempSkuAttr.setAttributeValueId(attrValueModel.getId());
						//添加新的属性值(如size 37)
						newSku.getSkuAttributes().add(tempSkuAttr);
						break;
					}
				}
				saveNewSku(newSku);
			}
		}
		return result;
	}
	
	
	public ExecuteResult<String> addSkuToDatabase(GoodsSkuModel skuModel, String[] selectedAttributeValues) {
		ExecuteResult<String> result = new ExecuteResult<String>();
		HashMap<Long, List<GoodsAttributeValueModel>> attributeMap = prepareSkuAttributeValue(selectedAttributeValues);		
		
		result = checkSelectAllAttribute(skuModel.getItemId(),attributeMap.keySet());
		if(!result.isSuccess()){
			return result;
		}
		List<GoodsSkuModel> skuList = findByItemIdWithAttrValues(skuModel.getItemId());
		if(CollectionUtils.isNotEmpty(skuList)){
			//在数据库中已经存在关于这个item的sku, 那么就是更新操作了
			result = updateSkuToDatabase(skuModel,selectedAttributeValues);
			return result;
		}
		
		int size = attributeMap.values().size();
		ArrayList<List<GoodsAttributeValueModel>> mapValueList = new ArrayList<List<GoodsAttributeValueModel>>();
		mapValueList.addAll(attributeMap.values());
		List<GoodsSkuModel> listSku = new ArrayList<GoodsSkuModel>();
		listSku.add(skuModel);
		for (int index = 0; index < size; index++) {
			listSku = buildGoodsSkuModel(listSku, mapValueList.get(index));
		}
		for (int index = 0; index < listSku.size(); index++) {
			GoodsSkuModel skuTemp = listSku.get(index);
			saveNewSku(skuTemp);
		}
		return result;
	}

	public void saveNewSku(GoodsSkuModel newSkuModel){
		newSkuModel.setId(null);
		addModel(newSkuModel);
		Set<GoodsSkuAttributeModel> skuAttributeSetTemp = newSkuModel.getSkuAttributes();
		if (skuAttributeSetTemp != null) {
			for (GoodsSkuAttributeModel skuAttribute : skuAttributeSetTemp) {
				skuAttribute.setId(null);
				skuAttribute.setItemId(newSkuModel.getItemId());
				skuAttribute.setSkuId(newSkuModel.getId());
				skuAttribute.setStatus(StatusEnum.ACTIVE.getId());
				skuAttribute.setCreator(newSkuModel.getCreator());
				skuAttribute.setModifiedBy(newSkuModel.getModifiedBy());
				goodsSkuAttributeService.addModel(skuAttribute);
			}
		}
	}
	
	private List<GoodsSkuModel> buildGoodsSkuModel(List<GoodsSkuModel> listSku, List<GoodsAttributeValueModel> attributeValueList){
		List<GoodsSkuModel> listSkuAll = new ArrayList<GoodsSkuModel>();
		for (int index = 0; index < attributeValueList.size(); index++) {
			List<GoodsSkuModel> listTemp = null;
			listTemp = cloneSkuList(listSku);
			GoodsAttributeValueModel attributeValue = attributeValueList.get(index);			
			for (GoodsSkuModel one : listTemp) {
				GoodsSkuAttributeModel oneSkuAttribute = buildSkuAttribute(attributeValue);
				Set<GoodsSkuAttributeModel> setTemp=one.getSkuAttributes();
				setTemp.add(oneSkuAttribute);
			}
			listSkuAll.addAll(listTemp);
		}
		return listSkuAll;
	}

	private GoodsSkuModel cloneSku(GoodsSkuModel originalGoodsSku){
		GoodsSkuModel tempSkuModel = new GoodsSkuModel();
		BeanUtils.copyProperties(originalGoodsSku, tempSkuModel);
		Set<GoodsSkuAttributeModel> skuAttributes = new LinkedHashSet<GoodsSkuAttributeModel>();
		for (GoodsSkuAttributeModel oneSkuAttribute : originalGoodsSku.getSkuAttributes()) {
				GoodsSkuAttributeModel tempAttribute = new GoodsSkuAttributeModel();
				BeanUtils.copyProperties( oneSkuAttribute,tempAttribute);			
				skuAttributes.add(tempAttribute);
		}
		tempSkuModel.setSkuAttributes(skuAttributes);	
		return tempSkuModel;
	}
	
	private List<GoodsSkuModel> cloneSkuList(List<GoodsSkuModel> listSku) {
		List<GoodsSkuModel> listTemp = new ArrayList<GoodsSkuModel>();
		for (GoodsSkuModel skuModel : listSku) {
			GoodsSkuModel tempSkuModel = cloneSku(skuModel);
			listTemp.add(tempSkuModel);
		}
		return listTemp;
	}

	private GoodsSkuAttributeModel buildSkuAttribute(GoodsAttributeValueModel goodsAttributeValue) {
		GoodsSkuAttributeModel oneAttributeModel = new GoodsSkuAttributeModel();
		oneAttributeModel.setAttributeCode(goodsAttributeValue.getGoodsAttribute().getCode());
		oneAttributeModel.setAttributeId(goodsAttributeValue.getGoodsAttribute().getId());
		oneAttributeModel.setAttributeValue(goodsAttributeValue.getValue());
		oneAttributeModel.setAttributeValueId(goodsAttributeValue.getId());
		return oneAttributeModel;
	}
	
	
	

}
